module klang.编译.输出节点.输出节点_;
import 全局;
import klang.编译.核心.核心_: 整数_, 创建数组, addRange;
import klang.编译.语法节点.节点_: 源文件_, 节点_;
import klang.编译.类型.类型_: 文本范围_, 注释范围_, 源映射范围_;
import klang.编译.工具.工具_: 获取节点的源文件, getParseTreeNode_1, isParseTreeNode;
import klang.编译.类型.枚举值.枚举值_: SK;
enum EmitFlags : long {
    None = 0L,
    SingleLine = 1L,
    AdviseOnEmitNode = 2L,
    NoSubstitution = 4L,
    CapturesThis = 8L,
    NoLeadingSourceMap = 16L,
    NoTrailingSourceMap = 32L,
    NoSourceMap = 48L,
    NoNestedSourceMaps = 64L,
    NoTokenLeadingSourceMaps = 128L,
    NoTokenTrailingSourceMaps = 256L,
    NoTokenSourceMaps = 384L,
    NoLeadingComments = 512L,
    NoTrailingComments = 1024L,
    NoComments = 1536L,
    NoNestedComments = 2048L,
    HelperName = 4096L,
    ExportName = 8192L,
    LocalName = 16384L,
    InternalName = 32768L,
    Indented = 65536L,
    NoIndentation = 131072L,
    AsyncFunctionBody = 262144L,
    ReuseTempVariableScope = 524288L,
    CustomPrologue = 1048576L,
    NoHoisting = 2097152L,
    HasEndOfDeclarationMarker = 4194304L,
    Iterator = 8388608L,
    NoAsciiEscaping = 16777216L,
    /*@internal*/ TypeScriptClassWrapper = 33554432L,
    /*@internal*/ NeverApplyImportHelper = 67108864L,
    /*@internal*/ IgnoreSourceNewlines = 134217728L,
    不缩进合成块_ = 268435456L,
    不输出空语句_ = 536870912L,
    标识符输出为文本_ = 1073741824L
}
class 合成注释_ : 注释范围_ {
    int 前方新行数量;
    bool 有前方新行;
    dstring 内容;
    this() { }
    this(SK kind, dstring text, long pos, long end, bool 有前方新行, bool 有尾随新行) {
        super(pos, end, 有尾随新行);
        this.前方新行数量 = 0;
        this.种类 = kind;
        this.内容 = text;
        this.有前方新行 = 有前方新行;
    }
}
class 输出节点_ {
    EmitFlags 标志;
    节点_[] 注释节点组;
    文本范围_ commentRange;
    源映射范围_ sourceMapRange;
    合成注释_[] leadingComments; // Synthesized leading comments
    合成注释_[] trailingComments; // Synthesized trailing comments
    源映射范围_[] tokenSourceMapRanges; // The text range to use when emitting source mappings for tokens
    dstring constantValue; // The constant value of an expression
    节点_ externalHelpersModuleName; // The local name for an imported helpers module
    bool startsOnNewLine; // If the node should begin on a new line
    this() { }
    this(EmitFlags 标志) {
        this.标志 = 标志;
    }
}
节点_ getOriginalNode_1(节点_ node) {
    return .getOriginalNode_2(node, (节点_ n) { return n !is ··null!(节点_); });
}
节点_ getOriginalNode_2(节点_ node, bool delegate(节点_) nodeTest) {
    if (node !is ··null!(节点_)) {
        while(node.原始节点 !is ··null!(节点_)) {
            node = node.原始节点;
        }
    }
    if (nodeTest(node)) {
        return node;
    }
    return ··null!(节点_);
}
输出节点_ getOrCreateEmitNode(节点_ node) {
    if (node.输出节点 is ··null!(输出节点_)) {
        if (isParseTreeNode(node)) {
            // To avoid holding onto transformation artifacts, we keep track of any
            // parse tree node we are annotating. This allows us to clean them up after
            // all transformations have completed.
            if (node.种类 == SK.源文件) {
                输出节点_ 结果 = new 输出节点_(EmitFlags.None);
                结果.注释节点组 = 创建数组!(节点_)(); // (节点_[]).([node]);
                .追加!(节点_)(结果.注释节点组, node);
                node.输出节点 = 结果;
                return 结果;
            }
            节点_ n = getParseTreeNode_1(获取节点的源文件(node));
            if (n !is ··null!(节点_)) {
                源文件_ sourceFile = 获取节点的源文件(n);
                输出节点_ 输出 = .getOrCreateEmitNode(sourceFile);
                .追加!(节点_)(输出.注释节点组, node);
            }
            else {
                assert(false, "失败"c);
            }
        }
        node.输出节点 = new 输出节点_(EmitFlags.None);
    }
    return (cast(输出节点_)(node.输出节点));
}
T setEmitFlags(T)(T node, EmitFlags emitFlags) {
    .getOrCreateEmitNode(node).标志 = emitFlags;
    return node;
}
EmitFlags getEmitFlags(节点_ node) {
    输出节点_ emitNode = node.输出节点;
    if (emitNode !is ··null!(输出节点_)) {
        return (cast(输出节点_)(emitNode)).标志;
    }
    return EmitFlags.None;
}
文本范围_ getCommentRange(节点_ node) {
    if ((node.输出节点 !is ··null!(输出节点_)) && ((cast(输出节点_)(node.输出节点)).commentRange !is ··null!(文本范围_))) {
        return (cast(输出节点_)(node.输出节点)).commentRange;
    }
    return node;
}
/**
 * Sets `EmitFlags.NoComments` on a node and removes any leading and trailing synthetic comments.
 * @internal
 */
节点_ removeAllComments(节点_ node) {
    输出节点_ 输出节点 = .getOrCreateEmitNode(node);
    输出节点.标志 |= EmitFlags.NoComments;
    if (输出节点.leadingComments !is ··null!(合成注释_[])) { }
    if (输出节点.trailingComments !is ··null!(合成注释_[])) { }
    return node;
}
/**
 * Sets flags that control emit behavior 属于 a node.
 */
/* @internal */
节点_ addEmitFlags(节点_ node, EmitFlags emitFlags) {
    输出节点_ 输出节点 = .getOrCreateEmitNode(node);
    输出节点.标志 = 输出节点.标志 | emitFlags;
    return node;
}
/**
 * Sets a custom text range to use when emitting source maps.
 */
节点_ setSourceMapRange(节点_ node, 源映射范围_ range = ··null!(源映射范围_)) {
    .getOrCreateEmitNode(node).sourceMapRange = range;
    return node;
}
/**
 *  Gets a custom text range to use when emitting source maps.
 */
源映射范围_ getSourceMapRange(节点_ node) {
    if (node.输出节点 !is ··null!(输出节点_)) {
        if ((cast(输出节点_)(node.输出节点)).sourceMapRange !is ··null!(源映射范围_)) {
            return (cast(输出节点_)(node.输出节点)).sourceMapRange;
        }
    }
    return (cast(源映射范围_)(node));
}
/**
 * Gets the TextRange to use 循环 source maps 循环 a token 属于 a node.
 */
源映射范围_ getTokenSourceMapRange(节点_ node, long token) {
    if ((node.输出节点 !is ··null!(输出节点_)) && ((cast(输出节点_)(node.输出节点)).tokenSourceMapRanges !is ··null!(源映射范围_[])) && (cast(输出节点_)(node.输出节点)).tokenSourceMapRanges.length > token) {
        return (cast(输出节点_)(node.输出节点)).tokenSourceMapRanges[token];
    }
    return ··null!(源映射范围_);
}
/**
 * Sets the TextRange to use 循环 source maps 循环 a token 属于 a node.
 */
节点_ setTokenSourceMapRange(节点_ node, long token, 源映射范围_ range = ··null!(源映射范围_)) {
    输出节点_ 输出节点 = .getOrCreateEmitNode(node);
    if ((node.输出节点 !is ··null!(输出节点_)) && ((cast(输出节点_)(node.输出节点)).tokenSourceMapRanges is ··null!(源映射范围_[]))) {
        (cast(输出节点_)(node.输出节点)).tokenSourceMapRanges = 创建数组!(源映射范围_)();
    }
    源映射范围_[] tokenSourceMapRanges = (cast(输出节点_)(node.输出节点)).tokenSourceMapRanges;
    if (tokenSourceMapRanges.length < token - 1) {
        tokenSourceMapRanges.length += 5;
    }
    tokenSourceMapRanges[token] = range;
    return node;
}
/**
 * Gets a custom text range to use when emitting comments.
 */
/*@internal*/
bool getStartsOnNewLine(节点_ node) {
    if ((node.输出节点 !is ··null!(输出节点_)) && (cast(输出节点_)(node.输出节点)).startsOnNewLine) {
        return (cast(输出节点_)(node.输出节点)).startsOnNewLine;
    }
    return false;
}
/**
 * Sets a custom text range to use when emitting comments.
 */
/*@internal*/
节点_ setStartsOnNewLine(节点_ node, bool newLine) {
    .getOrCreateEmitNode(node).startsOnNewLine = newLine;
    return node;
}
/**
 * Sets a custom text range to use when emitting comments.
 */
节点_ setCommentRange(节点_ node, 文本范围_ range) {
    .getOrCreateEmitNode(node).commentRange = range;
    return node;
}
合成注释_[] getSyntheticLeadingComments(节点_ node) {
    if ((node.输出节点 !is ··null!(输出节点_)) && ((cast(输出节点_)(node.输出节点)).leadingComments !is ··null!(合成注释_[]))) {
        return (cast(输出节点_)(node.输出节点)).leadingComments;
    }
    return ··null!(合成注释_[]);
}
节点_ setSyntheticLeadingComments(节点_ node, 合成注释_[] comments = ··null!(合成注释_[])) {
    .getOrCreateEmitNode(node).leadingComments = comments;
    return node;
}
节点_ 添加合成的前方注释(节点_ node, 合成注释_ comments) {
    合成注释_[] 合成前方注释 = .getSyntheticLeadingComments(node);
    if (合成前方注释 is ··null!(合成注释_[])) {
        合成前方注释 = 创建数组!(合成注释_)();
        .追加!(合成注释_)(合成前方注释, comments);
    }
    else {
        .追加!(合成注释_)(合成前方注释, comments);
    }
    return .setSyntheticLeadingComments(node, 合成前方注释);
}
节点_ addSyntheticLeadingComment(节点_ node, SK kind, dstring text, bool 有尾随新行) {
    合成注释_[] 合成前方注释 = .getSyntheticLeadingComments(node);
    if (合成前方注释 is ··null!(合成注释_[])) {
        合成前方注释 = 创建数组!(合成注释_)();
        .追加!(合成注释_)(合成前方注释, new 合成注释_(kind, text, -1, -1, false, 有尾随新行));
    }
    else {
        .追加!(合成注释_)(合成前方注释, new 合成注释_(kind, text, -1, -1, false, 有尾随新行));
    }
    return .setSyntheticLeadingComments(node, 合成前方注释);
}
合成注释_[] getSyntheticTrailingComments(节点_ node) {
    if ((node.输出节点 !is ··null!(输出节点_)) && ((cast(输出节点_)(node.输出节点)).trailingComments !is ··null!(合成注释_[]))) {
        return (cast(输出节点_)(node.输出节点)).trailingComments;
    }
    return ··null!(合成注释_[]);
}
节点_ setSyntheticTrailingComments(节点_ node, 合成注释_[] comments = ··null!(合成注释_[])) {
    .getOrCreateEmitNode(node).trailingComments = comments;
    return node;
}
节点_ addSyntheticTrailingComment(节点_ node, SK kind, dstring text, bool 有尾随新行) {
    合成注释_[] 合成尾随新行组 = .getSyntheticTrailingComments(node);
    if (合成尾随新行组 is ··null!(合成注释_[])) {
        合成尾随新行组 = 创建数组!(合成注释_)();
        .追加!(合成注释_)(合成尾随新行组, new 合成注释_(kind, text, -1, -1, false, 有尾随新行));
    }
    else {
        .追加!(合成注释_)(合成尾随新行组, new 合成注释_(kind, text, -1, -1, false, 有尾随新行));
    }
    return .setSyntheticTrailingComments(node, 合成尾随新行组);
}
节点_ moveSyntheticComments(节点_ node, 节点_ original) {
    .setSyntheticLeadingComments(node, .getSyntheticLeadingComments(original));
    .setSyntheticTrailingComments(node, .getSyntheticTrailingComments(original));
    输出节点_ emit = .getOrCreateEmitNode(original);
    if (emit.leadingComments !is ··null!(合成注释_[])) { }
    if (emit.trailingComments !is ··null!(合成注释_[])) { }
    return node;
}
/**
 * Gets the constant value to emit 循环 an expression representing an enum.
 */
dstring getConstantValue(节点_ node) {
    return (cast(输出节点_)(node.输出节点)).constantValue;
}
/**
 * Sets the constant value to emit 循环 an expression.
 */
节点_ setConstantValue(节点_ node, dstring value) {
    输出节点_ 输出节点 = .getOrCreateEmitNode(node);
    输出节点.constantValue = value;
    return node;
}
/* @internal */
节点_ ignoreSourceNewlines(节点_ node) {
    .getOrCreateEmitNode(node).标志 |= EmitFlags.IgnoreSourceNewlines;
    return node;
}
void disposeEmitNodes(源文件_ sourceFile = ··null!(源文件_)) {
    节点_ 节点 = getParseTreeNode_1(sourceFile);
    if (节点 !is ··null!(节点_)) {
        源文件_ sou = 获取节点的源文件(节点);
        if ((sou !is ··null!(源文件_)) && (sou.输出节点 !is ··null!(输出节点_))) {
            输出节点_ 输出节点 = (cast(输出节点_)(sou.输出节点));
            if (输出节点.注释节点组 !is ··null!(节点_[])) {
                节点_[] 注释节点组 = 输出节点.注释节点组;
                foreach (节点_ node; 注释节点组) {
                    if (node.输出节点 !is ··null!(输出节点_)) { }
                }
            }
        }
    }
}
T updateWithoutOriginal(T)(T updated, T 原始节点) {
    if (updated != 原始节点) {
        .setTextRange!(T)(updated, 原始节点);
    }
    return updated;
}
T updateWithOriginal(T)(T updated, T 原始节点) {
    if (updated != 原始节点) {
        .setOriginalNode!(节点_)((cast(节点_)(updated)), (cast(节点_)(原始节点)));
        .setTextRange!(T)(updated, 原始节点);
    }
    return updated;
}
T setOriginalNode(T)(T node, 节点_ 原始节点 = ··null!(节点_)) {
    node.原始节点 = 原始节点;
    if (原始节点 !is ··null!(节点_)) {
        输出节点_ 输出节点 = 原始节点.输出节点;
        if (输出节点 !is ··null!(输出节点_)) {
            node.输出节点 = .mergeEmitNode(输出节点, node.输出节点);
        }
    }
    return node;
}
T setTextRange(T)(T range, 文本范围_ location = ··null!(文本范围_)) {
    return location ? .setTextRangePosEnd!(T)(range, location.开始, location.结束) : range;
}
/**
 * Bypasses immutability and directly sets the `开始` property of a `TextRange` or `Node`.
 */
/* @internal */
T setTextRangePos(T)(T range, long 开始) {
    range.开始 = 开始;
    return range;
}
/**
 * Bypasses immutability and directly sets the `结束` property of a `TextRange` or `Node`.
 */
/* @internal */
T setTextRangeEnd(T)(T range, long 结束) {
    range.结束 = 结束;
    return range;
}
/**
 * Bypasses immutability and directly sets the `开始` and `结束` properties of a `TextRange` or `Node`.
 */
/* @internal */
T setTextRangePosEnd(T)(T range, long 开始, long 结束) {
    return .setTextRangeEnd!(T)(.setTextRangePos!(T)(range, 开始), 结束);
}
/**
 * Bypasses immutability and directly sets the `开始` and `结束` properties of a `TextRange` or `Node` from the
 * provided position and 宽度.
 */
/* @internal */
T setTextRangePosWidth(T)(T range, long 开始, long 宽度) {
    return .setTextRangePosEnd!(T)(range, 开始, 开始 + 宽度);
}
输出节点_ mergeEmitNode(输出节点_ sourceEmitNode, 输出节点_ destEmitNode = ··null!(输出节点_)) {
    EmitFlags 标志 = sourceEmitNode.标志;
    合成注释_[] leadingComments = sourceEmitNode.leadingComments;
    合成注释_[] trailingComments = sourceEmitNode.trailingComments;
    文本范围_ commentRange = sourceEmitNode.commentRange;
    源映射范围_ sourceMapRange = sourceEmitNode.sourceMapRange;
    源映射范围_[] tokenSourceMapRanges = sourceEmitNode.tokenSourceMapRanges;
    dstring constantValue = sourceEmitNode.constantValue;
    bool startsOnNewLine = sourceEmitNode.startsOnNewLine;
    if (destEmitNode is ··null!(输出节点_)) {
        destEmitNode = new 输出节点_(EmitFlags.None);
    }
    // We are using `.slice()` here in case `destEmitNode.leadingComments` is pushed to later.
    if (leadingComments !is ··null!(合成注释_[])) {
        if (destEmitNode.leadingComments is ··null!(合成注释_[])) {
            destEmitNode.leadingComments = 创建数组!(合成注释_)();
        }
        合成注释_[] 前面 = leadingComments[0 .. $];
        destEmitNode.leadingComments = addRange!(合成注释_)(前面, destEmitNode.leadingComments);
    }
    if (trailingComments !is ··null!(合成注释_[])) {
        if (destEmitNode.trailingComments is ··null!(合成注释_[])) {
            destEmitNode.trailingComments = 创建数组!(合成注释_)();
        }
        合成注释_[] 前面 = trailingComments[0 .. $];
        destEmitNode.trailingComments = addRange!(合成注释_)(前面, destEmitNode.trailingComments);
    }
    if (标志 != EmitFlags.None) {
        destEmitNode.标志 = 标志;
    }
    if (commentRange !is ··null!(文本范围_)) {
        destEmitNode.commentRange = commentRange;
    }
    if (sourceMapRange !is ··null!(源映射范围_)) {
        destEmitNode.sourceMapRange = sourceMapRange;
    }
    if (tokenSourceMapRanges !is ··null!(源映射范围_[])) {
        destEmitNode.tokenSourceMapRanges = .mergeTokenSourceMapRanges(tokenSourceMapRanges, destEmitNode.tokenSourceMapRanges);
    }
    if (constantValue !is ··null!(dstring)) {
        destEmitNode.constantValue = constantValue;
    }
    if (startsOnNewLine) {
        destEmitNode.startsOnNewLine = startsOnNewLine;
    }
    return destEmitNode;
}
源映射范围_[] mergeTokenSourceMapRanges(源映射范围_[] sourceRanges, 源映射范围_[] destRanges) {
    if (destRanges is ··null!(源映射范围_[])) {
        destRanges = 创建数组!(源映射范围_)();
    }
    foreach (size_t k, 源映射范围_ v; sourceRanges) {
        destRanges[k] = v;
    }
    return destRanges;
}
